/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.tue.nl.aa;

import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author waldo
 */
public class PkChoices {
    
    private ArrayList<MachineDTO> m;
    private ArrayList<JobDTO> t;
    private static final Random r = new Random();
    
    /**
     * Constructor.
     * @param nMachines , amount of machines. Must be 2 at least.
     * @param t , list of jobs.
     * @throws Exception 
     */
    public PkChoices( ArrayList<JobDTO> t, int nMachines )
    throws Exception{
        if( nMachines<2 || t.isEmpty() )
            throw new java.lang.Exception("At least two required machines and a non-empty jobs array.");
        this.t = t;
        m = new ArrayList<MachineDTO>();
        for( int i=0;i<nMachines;i++ ) m.add(new MachineDTO());
    }
    
    /**
     * Applies the "Power of k choices" algorithm.
     * @param  k machines to consider. It must be 1 at least and nMachines at most.
     */
    public void doLoadBalancing( int k )
    throws Exception{
        if( k>m.size()||k<1 ) throw new Exception("k must be 1 at least and "+m.size()+" at most... invalid k value:"+k);
        JobDTO job;
        int i; int chosenMachine;
        for( int j=0; j<t.size(); j++ ){
            int[] nm = new int[k];
            nm[0] = r.nextInt( m.size() );
            for( i=1; i<k; i++ ) do{
                nm[i] = r.nextInt( m.size() );
            } while( nm[i-1]==nm[i] );
            job = t.get(j);
            chosenMachine=0;
            for( i=1; i<k; i++ ){
                if( m.get(nm[chosenMachine]).compareTo(m.get(nm[i]))!=-1 )
                    chosenMachine=i;
            }
            m.get(nm[chosenMachine]).addJob(job);
        }
    }

    /**
     * @return set of machines, with assigned jobs.
     */
    public ArrayList<MachineDTO> getResult(){ return m; }
    /**
     * @return set of jobs.
     */
    public ArrayList<JobDTO> getJobs(){ return t; }

}
